#include "scan_mdns_service.h"
#include "mdns_common.h"

namespace OHOS::Scan {
using namespace OHOS::NetManagerStandard;

void ScanMdnsService::SetServiceType(std::string stype) {
	_serviceInfo.type = stype;
	_serviceInfo.port = 5353;
	_scanMDnsDiscoveryCallBack = new (std::nothrow) ScanMDnsDiscoveryObserver( _serviceInfo );
	_scanMDnsResolveCallBack = new (std::nothrow) ScanMDnsResolveObserver(_serviceInfo);

}

MDnsServiceInfo& ScanMdnsService::GetServiceInfo() {
	return _serviceInfo;
}

void ScanMdnsService::SetServiceInfo(const MDnsServiceInfo &info) {
	_serviceInfo = info;
}

sptr<ScanMDnsDiscoveryObserver> ScanMdnsService::GetMDnsDiscoveryCallBack() {
	return _scanMDnsDiscoveryCallBack;
}

void ScanMdnsService::SetMDnsDiscoveryCallBack(sptr<ScanMDnsDiscoveryObserver>& cb) {
	_scanMDnsDiscoveryCallBack = cb;
}

sptr<ScanMDnsResolveObserver> ScanMdnsService::GetMDnsResolveCallBack() {
	return _scanMDnsResolveCallBack;
}

void ScanMdnsService::SetMDnsResolveCallBack(sptr<ScanMDnsResolveObserver>& cb) {
	_scanMDnsResolveCallBack = cb;
}

bool ScanMdnsService::onStartDiscoverService() {
	SCAN_HILOGE("GetScannerList Enter ScanMdnsService");
	if (_scanMDnsDiscoveryCallBack == nullptr) {
		SCAN_HILOGE("GetScannerList onStartDiscoverService1 nullptr");
		return false;
	}
	SCAN_HILOGE("GetScannerList onStartDiscoverService begin");
	int32_t ret = DelayedSingleton<MDnsClient>::GetInstance()->StartDiscoverService(_serviceInfo.type, _scanMDnsDiscoveryCallBack);
	if (ret != NETMANAGER_EXT_SUCCESS) {
		return false;
	}
	SCAN_HILOGE("GetScannerList onStartDiscoverService end");
	return true;
}

bool ScanMdnsService::onResolveService(MDnsServiceInfo& serviceInfo) {
	SCAN_HILOGE("GetScannerList onResolveService");
	if (_scanMDnsResolveCallBack == nullptr) {
		SCAN_HILOGE("GetScannerList _scanMDnsResolveCallBack null fail");
		return false;
	}
	int32_t ret = DelayedSingleton<MDnsClient>::GetInstance()->ResolveService(serviceInfo, _scanMDnsResolveCallBack);
	if (ret != NETMANAGER_EXT_SUCCESS) {
		SCAN_HILOGE("GetScannerList onResolveService false");
		return false;
	}
	SCAN_HILOGE("GetScannerList onResolveService1 success");
	return true;
}

bool ScanMdnsService::onStopDiscoverService(){
	SCAN_HILOGE("GetScannerList onStopDiscoverService");
	if (_scanMDnsDiscoveryCallBack == nullptr) {
		SCAN_HILOGE("GetScannerList _scanMDnsDiscoveryCallBack null fail");
		return false;
	}
	int32_t ret = DelayedSingleton<MDnsClient>::GetInstance()->StopDiscoverService(_scanMDnsDiscoveryCallBack);
	if (ret != NETMANAGER_EXT_SUCCESS) {
		SCAN_HILOGE("GetScannerList onStopDiscoverService false");
		return false;
	}
	SCAN_HILOGE("GetScannerList onStopDiscoverService success");
	return true;	
}

void ScanMDnsDiscoveryObserver::HandleServiceFound(const MDnsServiceInfo &info, int32_t retCode) {
	SCAN_HILOGE("GetScannerList Enter HandleServiceFound");
	MDnsServiceInfo tempInfo = info;
	SCAN_HILOGE("GetScannerList HandleServiceFound [%{public}s][%{public}s][%{public}d][%{public}s]", info.name.c_str(), info.type.c_str(), info.port,info.addr.c_str());
	ScanMdnsService::GetInstance().onResolveService(tempInfo);
}

void ScanMDnsResolveObserver::HandleResolveResult(const MDnsServiceInfo &info, int32_t retCode) {
	SCAN_HILOGE("GetScannerList Enter HandleResolveResult");
	_serviceInfo = info;
	SCAN_HILOGE("GetScannerList HandleResolveResult [%{public}s][%{public}s][%{public}d][%{public}s]", info.name.c_str(), info.type.c_str(), info.port,info.addr.c_str());
	MDnsServiceInfo tempInfo = info;
	auto texRecord = tempInfo.GetAttrMap();
	auto textIt = texRecord.begin();
	for (; textIt != texRecord.end(); textIt++) {
		SCAN_HILOGE("GetScannerList startHandleServiceResolve keys [%{public}s]", textIt->first.c_str());
	}

	ScanMdnsService::GetInstance().ToMDnsScaner(tempInfo);
}

void ScanMDnsDiscoveryObserver::HandleStopDiscover(const MDnsServiceInfo &serviceInfo, int32_t retCode) {
	SCAN_HILOGE("GetScannerList Enter HandleStopDiscover");
	MDnsServiceInfo info = serviceInfo;
	SCAN_HILOGE("GetScannerList HandleStopDiscover [%{public}s][%{public}s][%{public}d][%{public}s]", info.name.c_str(), info.type.c_str(), info.port,info.addr.c_str());
}

void ScanMdnsService::ToMDnsScaner(MDnsServiceInfo& serviceInfo) {
	std::unique_ptr<ScanDeviceInfoTCP> scannerInfo = std::make_unique<ScanDeviceInfoTCP>();
	scannerInfo->addr=serviceInfo.addr;
	scannerInfo->deviceName=serviceInfo.name;
	scannerInfo->port=serviceInfo.port;
	std::vector<std::string> keys={"UUID", "adminur", "button", "feeder", "mdl","mfg","mote","txtvers","ty"};
	std::string deviceUUID;
	for(auto key:keys){
		std::string value = ScanMdnsService::GetServiceAttribute(serviceInfo, key);
        if (value.empty()) {
			SCAN_HILOGE("GetScannerList key [%{public}s] is empty",key.c_str());
            continue;
        }
        SCAN_HILOGE("GetScannerList key:[%{public}s] value:[%{public}s]",key.c_str(),value.c_str());
		if(key == "UUID"){
			deviceUUID = value;
			scannerInfo->uuid = value;
		}else if(key == "mdl"){
			scannerInfo->model = value;
		}else if(key == "mfg"){
			scannerInfo->manufacturer = value;
		}else if(key == "ty"){
			scannerInfo->deviceType = value;
		}else if(key == "port"){
			scannerInfo->port = value;
		}else if(key == "button"){
			scannerInfo->button = value;
		}else if(key == "feeder"){
			scannerInfo->feeder = value;
		}
	}
	ScanServiceAbility::GetInstance()->SendDeviceInfoTCP(*scannerInfo,"scanDeviceFoundTCP");
}

std::string ScanMdnsService::GetServiceAttribute(MDnsServiceInfo &serviceInfo, std::string keyStr) {
	SCAN_HILOGE("GetScannerList GetServiceAttribute keyStr [%{public}s]",keyStr.c_str());
	TxtRecord attrMap = serviceInfo.GetAttrMap();
	auto attrArrSize = attrMap.size();
	if (attrArrSize < 1) {
		SCAN_HILOGE("can not get attr");
		return "";
	}
	auto attrIt = attrMap.find(keyStr);
	if (attrIt == attrMap.end()) {
		SCAN_HILOGE("can not find key");
		return "";
	}
	std::string value = "";
	for(auto num:attrMap[keyStr]) {
		value+=num;
	}
	return value;
}


}